import Result from '../util/result';

interface ApiError {
  code: number;
  errors: string;
  message: string;
  status: number;
}

const isApiError = (x: any): x is ApiError => (!!x);

module.exports = () => async function errorHandler(ctx, next) {
  try {
    await next();
  } catch (err) {
    if (isApiError(err)) {
      const { TEST_LOG } = process.env;
      // 所有的异常都在 app 上触发一个 error 事件，框架会记录一条错误日志
      if (TEST_LOG !== 'no-log') {
        ctx.app.emit('error', err, ctx);
      }

      const status = err.status || 500;
      // 生产环境时 500 错误的详细错误内容不返回给客户端，因为可能包含敏感信息
      const error = status === 500 && ctx.app.config.env === 'prod'
        ? 'Internal Server Error'
        : err.message;

      // 从 error 对象上读出各个属性，设置到响应中
      ctx.body = new Result(undefined, undefined, error);

      if (status === 422) {
        ctx.body = new Result(undefined, undefined, err.errors);
      }
      ctx.status = status;
    }
  }
};
